package org.openclinic.controller;

import java.text.SimpleDateFormat;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.validation.Valid;

import org.openclinic.domain.HealthProfessional;
import org.openclinic.exception.AbstractExceptionHandler;
import org.openclinic.exception.DomainException;
import org.openclinic.service.HealthInsuranceService;
import org.openclinic.service.HealthProfessionalService;
import org.openclinic.service.MedicalSpecialtyService;
import org.openclinic.to.DataTablesTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

@Controller
@SessionAttributes("healthProfessional")
public class HealthProfessionalController extends AbstractExceptionHandler {

	@Autowired
	private HealthProfessionalService healthProfessionalService;
	
	@Autowired
	private HealthInsuranceService insuranceService;

	@Autowired
	private MedicalSpecialtyService medicalSpecialtyService;
	
	@InitBinder
	public void initBinder(WebDataBinder binder) {
		binder.registerCustomEditor(Date.class, "birthdate", new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true));
		binder.registerCustomEditor(Set.class, "specialties", new CustomCollectionEditor(Set.class) {
			@Override
			protected Object convertElement(Object element) {
				Long id = null;
	
				if (element instanceof String && !((String) element).equals("")) {
					// convertendo post do JSP trata-se como string
					try {
						id = Long.parseLong((String) element);
					} catch (NumberFormatException e) {
						e.printStackTrace();
					}
				} else if (element instanceof Long) {
					// carregando da base de dados trata-se como long
					id = (Long) element;
				}
	
				return id != null ? medicalSpecialtyService.find(id) : null;
			}
		});
	}
	
	@ResponseBody
	@RequestMapping(value = "/healthProfessional/delete.action", method = RequestMethod.POST)
	public boolean delete(@RequestParam long id) {
		healthProfessionalService.delete(id);
		return true;
	}
	
	@ResponseBody
	@RequestMapping(value = "/healthProfessional/findBySpecialty.action", method = RequestMethod.POST)
	public List<AbstractMap.SimpleEntry<String, Long>> findBySpecialty(@RequestParam long specialtyId) {
		List<AbstractMap.SimpleEntry<String, Long>> professionals = new ArrayList<AbstractMap.SimpleEntry<String, Long>>();
		List<HealthProfessional> completeList = healthProfessionalService.findBySpecialty(specialtyId);
		for (HealthProfessional hp : completeList) {
			professionals.add(new AbstractMap.SimpleEntry<String, Long>(hp.getName(), hp.getUserId()));
		}
		return professionals;
	}
	
	@RequestMapping(value = "/healthProfessional.do", method = RequestMethod.GET)
	public ModelAndView init() {
		ModelAndView modelAndView = new ModelAndView("user.view");
		modelAndView.addObject("userDesignation", "Profissional de Sa&uacute;de");
		modelAndView.addObject("bond", "healthProfessional");
		
		return modelAndView;
	}

	@RequestMapping(value = "/healthProfessional/open.diag", method = RequestMethod.POST)
	public ModelAndView initNewForm(@RequestParam Long id) {	
		ModelAndView modelAndView = new ModelAndView("user-form.jsp");
		modelAndView.addObject("bond", "healthProfessional");
		modelAndView.addObject("insuranceList", insuranceService.list());
		modelAndView.addObject("specialtyList", medicalSpecialtyService.list());
		
		if (id == null) {
			modelAndView.addObject("healthProfessional", new HealthProfessional());
		} else {
			modelAndView.addObject("healthProfessional", healthProfessionalService.find(id));
		}
		
		return modelAndView;
	}
	
	@ResponseBody
	@RequestMapping(value = "/healthProfessional/list.action", method = RequestMethod.POST)
	public DataTablesTO<HealthProfessional> list() {
		return new DataTablesTO<HealthProfessional>(healthProfessionalService.list());
	}
	
	@ResponseBody
	@RequestMapping(value = "/healthProfessional/save.action", method = RequestMethod.POST)
	public HealthProfessional save(@Valid @ModelAttribute HealthProfessional healthProfessional, BindingResult validationResult) {
		if(!validationResult.hasErrors()) {
			healthProfessionalService.save(healthProfessional);
			healthProfessional.setHealthInsurance(insuranceService.find(healthProfessional.getHealthInsurance().getInsuranceId()));
			return healthProfessional;
		}
		throw new DomainException(validationResult.getAllErrors());
	}

}
